package client;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.BevelBorder;

import tools.Card;

import java.util.ArrayList;

/**
 *
 * @author Mateusz Domagała
 */
 
class ClientWindowAdapter extends WindowAdapter
{
	ClientBadugi c;
	
	ClientWindowAdapter(ClientBadugi c)
	{
		this.c = c;
	}
	
	public void windowClosing(WindowEvent windowEvent)
	{
		c.exit();
	}
}
        
public class ClientBadugi extends JPanel
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -5310000308545250418L;

	/* zmienne widoczne w pakiecie */
	/* obrazy kart */
	CardImages cardImages = new CardImages();
	
	/* zmienne prywatne - niewidoczne dla innych klas */
	private JLabel statusLabel;
	private JLabel serverStatus;
	private JLabel potStatus;
	private JLabel cardsStatusLabel; 
	
	private boolean isConnected = false;
	private final static String newline = "\n";
	/* obiekt obslugujacy polaczenie z serwerem */
	ClientControl clientControl;
	/* watek obslugujacy polaczenie z serwerm */
	private Thread threadControl;
	/* Lista paneli graczy widocznych w centrum okna, przy stole gry */
	private ArrayList<PlayerPanel> playerPanel = new ArrayList<PlayerPanel>(); 	
	/* panel boczny z przyciskami */
	private ButtonPanel buttonPanel;
	
	/* w trybie Bot bedzie komputerek myslal w tej klasie */
	private BotBadugi bot;
	
   ClientBadugi()
   {
   	setLayout(new BorderLayout());		
		setBorder(BorderFactory.createLineBorder(Color.black));
      
		statusLabel = new JLabel();
		setButtonPanel(new ButtonPanel(this));
		Dimension d = new Dimension(224, 735);
		getButtonPanel().setBounds(0, 0, 224, 735);
		getButtonPanel().setMaximumSize(d);
		getButtonPanel().setMinimumSize(d);
		getButtonPanel().setPreferredSize(d);
		add(getButtonPanel(), BorderLayout.EAST);
		
		/* status serwera */
		serverStatus = new JLabel();
		serverStatus.setForeground(Color.white);
		serverStatus.setFont( new Font(serverStatus.getFont().getFontName(), Font.BOLD, serverStatus.getFont().getSize()+1 ));
		
		/* Pula na stole */
		potStatus = new JLabel();
		potStatus.setForeground(Color.white);
		potStatus.setFont( new Font(potStatus.getFont().getFontName(), Font.BOLD, potStatus.getFont().getSize()+1 ));
		
		/* odgranicznik pomiedzy labelami z pula i statusem serwera */
		JLabel dummyLabel = new JLabel();
		
      /*
       * niewidoczny panel aby zajac indeks 0
       * 
       * */
		playerPanel.add(0, new PlayerPanel(this, 0));

      for(int i=1; i<7; i++)
      	playerPanel.add(i, new PlayerPanel(this, i));

      /* PANEL Z GRACZAMI - STOL */
      int width = 280;
      int height = 185;
      int halfHeight = (int)(height/2);
      int space = 1;
      
		JPanel tablePanel = new JPanel();
		tablePanel.setPreferredSize(new Dimension((3*width)+(2*space), (3*height)+(2*space)));
		tablePanel.setLayout(null);
		tablePanel.setBackground(new Color(0, 100, 0));
		
		playerPanel.get(4).setBounds(width+space, 0, width, height);
		tablePanel.add(playerPanel.get(4));
		
		playerPanel.get(5).setBounds((2*width)+(2*space), halfHeight+space, width, height);
		tablePanel.add(playerPanel.get(5));
		
		playerPanel.get(6).setBounds((2*width)+(2*space), (halfHeight+height)+(2*space), width, height);
		tablePanel.add(playerPanel.get(6));
		
		playerPanel.get(1).setBounds(width+space, (2*height)+(3*space), width, height);
		tablePanel.add(playerPanel.get(1));
		
		/* miejsce na pokazanie rozkladu kart gracza */
		
		cardsStatusLabel = new JLabel();
		cardsStatusLabel.setBounds((int)(2*width+3*space+77), (2*height)+(3*space)+halfHeight+24, (int)(width/1.5), (int)(height/4));
		cardsStatusLabel.setBackground(new Color(0, 100, 0));
		cardsStatusLabel.setForeground(Color.white);
		tablePanel.add(cardsStatusLabel);
		
		playerPanel.get(2).setBounds(0, (halfHeight+height)+(2*space), width, height);
		tablePanel.add(playerPanel.get(2));
		
		playerPanel.get(3).setBounds(0, halfHeight+space, width, height);
		tablePanel.add(playerPanel.get(3));

      add(tablePanel, BorderLayout.CENTER);
      tablePanel.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(0, 0, 0), null, null, null));
		
		/* panel srodkowy ze statusem serwera i pula */
		JPanel potPanel = new JPanel();
		potPanel.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(0, 0, 0), null, null, null));
		potPanel.setBackground(new Color(0, 100, 0));
		potPanel.setLayout(new GridBagLayout());
		potPanel.setBounds(width+space, height+space, width, (height)+space);
		
		JPanel statusServerPanel = new JPanel(); 
		statusServerPanel.setLayout(new BoxLayout(statusServerPanel, BoxLayout.Y_AXIS));
		statusServerPanel.setBackground(new Color(0, 100, 0));
		statusServerPanel.add(serverStatus);
		statusServerPanel.add(dummyLabel);
		statusServerPanel.add(potStatus);
		
		potPanel.add(statusServerPanel);
		serverStatus.setAlignmentX(CENTER_ALIGNMENT);
		dummyLabel.setAlignmentX(CENTER_ALIGNMENT);
		potStatus.setAlignmentX(CENTER_ALIGNMENT);		
		dummyLabel.setMaximumSize(new Dimension(20,20));
		dummyLabel.setMinimumSize(new Dimension(20,20));
		dummyLabel.setPreferredSize(new Dimension(20,20));

		tablePanel.add(potPanel);

		/* panel dolny z paskiem statusu */      
           
		add(statusLabel, BorderLayout.PAGE_END);
		statusLabel.setPreferredSize(new Dimension(500,20));
		statusLabel.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(0, 0, 0), null, null, null));

		Font f = statusLabel.getFont();
		statusLabel.setFont(new Font(f.getFontName(), Font.BOLD, 10));
		statusLabel.setForeground(Color.black);

		this.setBot(new BotBadugi(this));
   }
   
   void initPanels()
   {
   	initServerPanel();
   	for (PlayerPanel p: playerPanel)
   	{
   		p.initPanel();
   	}
   }
   
   private void initServerPanel()
   {
   	serverStatus.setText("");
   	potStatus.setText("");
   	cardsStatusLabel.setText("");
   }
   
   private void refreshServerPanel()
   {
   	if (this.isConnected)
   	{
   		serverStatus.setText(this.clientControl.gameState.getState());
   		potStatus.setText("Pot: " + this.clientControl.gameState.getPot());
   		if (this.clientControl.getPlayer().getHand() != null)
   			cardsStatusLabel.setText("Your best cards: "+this.clientControl.getPlayer().getHand().getCardsListAsString());
   		else
   			cardsStatusLabel.setText("");		
   	}
   	else
   	{
   		initServerPanel();
   		this.buttonPanel.initPanel();
   	}
   }
   
   void refreshPanels()
   {
   	refreshServerPanel();
   	for (PlayerPanel p: playerPanel)
   	{
   		p.refreshPanel();
   	}
   }
   
	public BotBadugi getBot()
	{
		return bot;
	}

	public void setBot(BotBadugi bot)
	{
		this.bot = bot;
	}

	void check()
	{
		System.out.println("ClientBadugi.check()");
		this.clientControl.check();
		this.buttonPanel.setOffBidButtons();
	}
	
	void bet(int bet)
	{
		System.out.println("ClientBadugi.bet()"+bet);
		this.clientControl.bet(bet);
		this.buttonPanel.setOffBidButtons();		
	}
	
	void raise(int bet)
	{
		System.out.println("ClientBadugi.raise()"+bet);
		this.clientControl.raise(bet);
		this.buttonPanel.setOffBidButtons();		
	}
	
	void call()
	{
		System.out.println("ClientBadugi.call()");
		this.clientControl.call();
		this.buttonPanel.setOffBidButtons();
	}
	
	void fold()
	{
		System.out.println("ClientBadugi.fold()");
		this.clientControl.fold();
		this.buttonPanel.setOffBidButtons();		
	}
	
	void allin()
	{
		System.out.println("ClientBadugi.allin()");
		this.clientControl.allin();
		this.buttonPanel.setOffBidButtons();
	}

	void exchangeCards()
	{
		System.out.println("ClientBadugi.exchangeCards()");
		this.clientControl.exchangeCards(this.getCheckedCards());
		this.buttonPanel.setOffExchangeCards();
	}
	
	void dontExchange()
	{
		System.out.println("ClientBadugi.dontExchange()");
		this.clientControl.dontExchange();
		this.buttonPanel.setOffExchangeCards();
	}

	private ArrayList<Card> getCheckedCards()
	{
		ArrayList<Card> cards = this.playerPanel.get(clientControl.id).getCheckedCard();
		this.playerPanel.get(clientControl.id).uncheckCards();
		return cards;
	}
	
	void closeConnection()
	{
		this.isConnected = false;
		this.clientControl = null;
		this.threadControl = null;
		this.setStatus("Disconnected");
		this.buttonPanel.clearCommunication();
	}
	
	boolean isBotMode()
	{
		return this.buttonPanel.isBotMode();
	}
	
	boolean isConnection()
	{
		return this.isConnected;
	}
	
	boolean connect(String ip, String port)
	{
		if (port.equals("") || ip.equals(""))
		{
			setStatus("Type IP address and port number");
			return false;
		}
		setStatus("Connecting, please wait...");
		try
		{
			int p = Integer.parseInt(port);
			
			this.clientControl = new ClientControl(ip, p, this);
			this.threadControl = new Thread(clientControl);
			this.threadControl.start();
			setStatus("Connected: "+ ip + ":" + port);
			isConnected = true;
		}
		catch (NumberFormatException e) 
		{
			setStatus("Wrong port number");
			isConnected = false;
			return false;
		}
		catch (Exception e) 
		{
			//e.printStackTrace();
			setStatus("Cannot connect to the server " + ip + ":" + port);
			isConnected = false;
			return false;
		}
		return true;
	}		
	
   void exit()
	{
   	if (isConnected)
   		this.clientControl.closeConnection(true);
		System.exit(0);
	}
	
	void setStatus(String s)
	{
		statusLabel.setText(s);
	}
	
	public ButtonPanel getButtonPanel()
	{
		return buttonPanel;
	}

	public void setButtonPanel(ButtonPanel buttonPanel)
	{
		this.buttonPanel = buttonPanel;
	}

	void setCommunication(String s)
	{
		getButtonPanel().setCommunication(s + ClientBadugi.newline);
	}
    /**
     * @param args the command line arguments
     */
   public static void main(String[] args)
   {
   	setLook();
		JFrame frame = new JFrame("Badugi - client - (c) Mateusz Domagala");
		ClientBadugi c = new ClientBadugi();
		frame.add(c);
		frame.addWindowListener(new ClientWindowAdapter(c));
		frame.setPreferredSize(new Dimension(1076,610));
		frame.pack();
		frame.setVisible(true);
		frame.setIconImage(c.cardImages.getImage("face_down"));
		frame.setResizable(false);
   }
   
   private static void setLook() //
   {
   	try 
   	{
   		// Set cross-platform Java L&F (also called "Metal")
   		//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
   		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
   	} 
   	catch (UnsupportedLookAndFeelException e) 
   	{
   		// handle exception
   	}
   	catch (ClassNotFoundException e) 
   	{
   		// handle exception
   	}
   	catch (InstantiationException e) 
   	{
   		// handle exception
   	}
   	catch (IllegalAccessException e) 
   	{
   		// handle exception
   	}
   }
}
